﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Media;

namespace Algoritmos_de_Ordenação.Algoritmos
{
    public class QuickSortRandom : DrawingRegion
    {
        public QuickSortRandom()
        {
        }
        
        public QuickSortRandom(TabItem tabItem)
            : base(tabItem, TabType.QuickRandom)
        {
        }
        int comparisons = 0;
        int swaps = 0;
        protected override void DoSort()
        {
            comparisons = 0;
            swaps = 0;
            sorted = false;            
            
            DoQuickSort(0, numElemArray - 1);

            endSorting(comparisons, swaps);
        }
        
        private void DoQuickSort(int p, int r)
        {
            if (p < r)
            {
                int q = Random_partition(p, r);
                DoQuickSort(p, q - 1);
                DoQuickSort(q + 1, r);
            }
        }

        private int Random_partition(int p, int r)
        {
            Random rn = new Random(unchecked((int)DateTime.Now.Ticks));

            int i = rn.Next(p, r);

            updateGBThread(14);
            wf ();
            compareTwoThread ( i, p );
            swaps++;
            swapTwoThread ( i, p );
            updateInformationsThread(SortStatus.Sorting, comparisons, swaps);

            int tempFora = numberArray[i];
            numberArray[i] = numberArray[p];//15
            numberArray[p] = tempFora;

            return partition(p, r);
        }

        private int partition(int p, int r)
        {
            int x = numberArray[r];
            int i = p - 1;
            updateGBThread(25);
            for (int j = p; j <= r - 1; j++)//26
            {
                
                wf();
                compareTwoThread(r, j);
                comparisons++;
                updateInformationsThread(SortStatus.Sorting, comparisons, swaps);
                updateGBThread(27);
                if (numberArray[j] <= x)//28
                {
                    i++;
                    swaps++;
                    wf();
                    swapTwoThread(i, j);

                    updateGBThread(28);
                    updateInformationsThread(SortStatus.Sorting, comparisons, swaps);
                    int temp = numberArray[i];
                    numberArray[i] = numberArray[j];//29
                    numberArray[j] = temp;
                }
            }
            compareTwoThread(r, i + 1);
            updateGBThread(31);
            wf();
            swapTwoThread(i + 1, r);
            swaps++;
            updateInformationsThread(SortStatus.Sorting, comparisons, swaps);

            int tempFora = numberArray[i + 1];
            numberArray[i + 1] = numberArray[r];//32
            numberArray[r] = tempFora;

            return i + 1;
        }

    }
}